home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / capbt848.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-22  |  10.0 KB  |  302 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. //
  18. //
  19. //
  20. //  This file is partially based off of bt848.c from dTV.
  21. //
  22. //    dTV Copyright (c) 2000 John Adcock.  All rights reserved.
  23.  
  24. #include <crtdbg.h>
  25. #include <windows.h>
  26. #include <commctrl.h>
  27. #include "resource.h"
  28. #include "Error.h"
  29. #include "dtvdrv.h"
  30.  
  31. extern const char g_szError[];
  32. extern HINSTANCE g_hInst;
  33.  
  34. struct dTVDriverData {
  35.     PIsDriverOpened                isDriverOpened;
  36.     PPCIGetHardwareResources    pciGetHardwareResources;
  37.     PMemoryAlloc                memoryAlloc;
  38.     PMemoryFree                    memoryFree;
  39.     PMemoryMap                    memoryMap;
  40.     PMemoryMap                    memoryUnmap;
  41.     PMemoryRead                    memoryReadBYTE;
  42.     PMemoryRead                    memoryReadWORD;
  43.     PMemoryRead                    memoryReadDWORD;
  44.     PMemoryWrite                memoryWriteBYTE;
  45.     PMemoryWrite                memoryWriteWORD;
  46.     PMemoryWrite                memoryWriteDWORD;
  47.  
  48.     DWORD                        dwMemoryBase;
  49.     DWORD                        dwMemoryLength;
  50.     DWORD                        dwPhysicalAddress;
  51. } g_dTVDriver;
  52.  
  53. static void InitializeBT8X8() {
  54.     DWORD ids[4][2]={
  55.         { 0x109e, 0x036e },
  56.         { 0x109e, 0x0350 },
  57.         { 0x109e, 0x0351 },
  58.         { 0x109e, 0x036f },
  59.     };
  60.  
  61.     for(int i=0; i<4; ++i) {
  62.         int ret;
  63.         DWORD dwPhysicalAddress = 0;
  64.         DWORD dwMemoryLength = 0;
  65.         DWORD dwSubSystemID = 0;
  66.  
  67.         ret = g_dTVDriver.pciGetHardwareResources(ids[i][0], ids[i][1], &dwPhysicalAddress,
  68.             &dwMemoryLength, &dwSubSystemID);
  69.  
  70.         if (ret == ERROR_SUCCESS) {
  71.             g_dTVDriver.dwMemoryBase = g_dTVDriver.memoryMap(dwPhysicalAddress, dwMemoryLength);
  72.  
  73.             if (!g_dTVDriver.dwMemoryBase)
  74.                 throw MyError("Found BT8X8 chip, but could not lock memory-mapped registers.");
  75.  
  76.             g_dTVDriver.dwPhysicalAddress = dwPhysicalAddress;
  77.             g_dTVDriver.dwMemoryLength = dwMemoryLength;
  78.  
  79.             return;
  80.         }
  81.  
  82.     }
  83.  
  84.     throw MyError("This function requires a video capture device based on the Brooktree (Conexant) "
  85.             "BT848(A), BT849, or BT878 chip.  None could be found.  Are you sure you have one?");
  86. }
  87.  
  88. static void DeinitializeBT8X8() {
  89.     g_dTVDriver.memoryUnmap(g_dTVDriver.dwPhysicalAddress, g_dTVDriver.dwMemoryLength);
  90. }
  91.  
  92. ///////////////////////////////////////////////////////////////////////////
  93.  
  94. BOOL CALLBACK CaptureBT848TweakerDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  95.     static const struct {
  96.         DWORD id;
  97.         DWORD offset;
  98.         DWORD bit;
  99.     } s_bits[]={
  100.         { IDC_LUMANOTCHEVEN,    0x02C, 0x80 },
  101.         { IDC_LUMANOTCHODD,        0x0AC, 0x80 },
  102.  
  103.         { IDC_LUMADECIMATEEVEN,    0x02C, 0x20 },
  104.         { IDC_LUMADECIMATEODD,    0x0AC, 0x20 },
  105.  
  106.         { IDC_CHROMAAGCENEVEN,    0x040, 0x40 },
  107.         { IDC_CHROMAAGCENODD,    0x0C0, 0x40 },
  108.         { IDC_CHROMAKILLEVEN,    0x040, 0x20 },
  109.         { IDC_CHROMAKILLODD,    0x0C0, 0x20 },
  110.  
  111.         { IDC_LUMAFULLRANGE,    0x048, 0x80 },
  112.  
  113.         { IDC_LUMACOMBEVEN,        0x04C, 0x80 },
  114.         { IDC_LUMACOMBODD,        0x0CC, 0x80 },
  115.         { IDC_CHROMACOMBEVEN,    0x04C, 0x40 },
  116.         { IDC_CHROMACOMBODD,    0x0CC, 0x40 },
  117.         { IDC_INTERLACEVSEVEN,    0x04C, 0x20 },
  118.         { IDC_INTERLACEVSODD,    0x0CC, 0x20 },
  119.  
  120.         { IDC_AGCCRUSH,            0x068, 0x01 },
  121.         { IDC_GAMMACORRECTION,    0x0D8, 0x10 },
  122.  
  123.         { IDC_LUMAPEAKEVEN,        0x040, 0x80 },
  124.         { IDC_LUMAPEAKODD,        0x0C0, 0x80 },
  125.         {0},
  126.     };
  127.     int i;
  128.  
  129.     switch(msg) {
  130.     case WM_INITDIALOG:
  131.         for(i=0; s_bits[i].id; ++i)
  132.             CheckDlgButton(hdlg, s_bits[i].id, (g_dTVDriver.memoryReadBYTE(s_bits[i].offset) & s_bits[i].bit) ? BST_CHECKED:BST_UNCHECKED);
  133.  
  134.         SendDlgItemMessage(hdlg, IDC_SLIDER_LUMAPEAKEVEN, TBM_SETRANGE, TRUE, MAKELONG(0, 3));
  135.         SendDlgItemMessage(hdlg, IDC_SLIDER_LUMAPEAKODD, TBM_SETRANGE, TRUE, MAKELONG(0, 3));
  136.         SendDlgItemMessage(hdlg, IDC_SLIDER_CORING, TBM_SETRANGE, TRUE, MAKELONG(0, 3));
  137.  
  138.         SendDlgItemMessage(hdlg, IDC_SLIDER_LUMAPEAKEVEN, TBM_SETPOS, TRUE, (g_dTVDriver.memoryReadBYTE(0x040)&0x18)>>3);
  139.         SendDlgItemMessage(hdlg, IDC_SLIDER_LUMAPEAKODD, TBM_SETPOS, TRUE, (g_dTVDriver.memoryReadBYTE(0x0c0)&0x18)>>3);
  140.         SendDlgItemMessage(hdlg, IDC_SLIDER_CORING, TBM_SETPOS, TRUE, (g_dTVDriver.memoryReadBYTE(0x048)&0x60)>>5);
  141.  
  142.         SendDlgItemMessage(hdlg, IDC_SLIDER_LEFT, TBM_SETRANGE, TRUE, MAKELONG(0, 10239));
  143.         SendDlgItemMessage(hdlg, IDC_SLIDER_RIGHT, TBM_SETRANGE, TRUE, MAKELONG(0, 10239));
  144.         SendDlgItemMessage(hdlg, IDC_SLIDER_VDELAY, TBM_SETRANGE, TRUE, MAKELONG(0, 256));
  145.         SendDlgItemMessage(hdlg, IDC_SLIDER_AGCDELAY, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
  146.         SendDlgItemMessage(hdlg, IDC_SLIDER_BURSTDELAY, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
  147.  
  148.         {
  149.             int hscale = g_dTVDriver.memoryReadBYTE(0x020)*256+g_dTVDriver.memoryReadBYTE(0x024) + 4096;
  150.             int hdelay = ((g_dTVDriver.memoryReadBYTE(0x00C)&0x0c)<<6)+(g_dTVDriver.memoryReadBYTE(0x018)&0xfe);
  151.             int hactive = ((g_dTVDriver.memoryReadBYTE(0x00C)&0x003)<<8)+g_dTVDriver.memoryReadBYTE(0x01c);
  152.             int left = MulDiv(hdelay,hscale,512);
  153.             int right = left + MulDiv(hactive, hscale,512);
  154.  
  155.             SendDlgItemMessage(hdlg, IDC_SLIDER_LEFT, TBM_SETPOS, TRUE,    left);
  156.             SendDlgItemMessage(hdlg, IDC_SLIDER_RIGHT, TBM_SETPOS, TRUE, right);
  157.         }
  158.  
  159.         SendDlgItemMessage(hdlg, IDC_SLIDER_VDELAY, TBM_SETPOS, TRUE,
  160.             ((g_dTVDriver.memoryReadBYTE(0x00C)&0xc0)<<2)+g_dTVDriver.memoryReadBYTE(0x010));
  161.  
  162.         SendDlgItemMessage(hdlg, IDC_SLIDER_AGCDELAY, TBM_SETPOS, TRUE,
  163.             g_dTVDriver.memoryReadBYTE(0x60));
  164.  
  165.         SendDlgItemMessage(hdlg, IDC_SLIDER_BURSTDELAY, TBM_SETPOS, TRUE,
  166.             g_dTVDriver.memoryReadBYTE(0x64));
  167.  
  168.         return TRUE;
  169.     case WM_COMMAND:
  170.         switch(LOWORD(wParam)) {
  171.         case IDOK:
  172.         case IDCANCEL:
  173.             EndDialog(hdlg, 0);
  174.             break;
  175.         default:
  176.             if (HIWORD(wParam) == BN_CLICKED)
  177.                 for(i=0; s_bits[i].id; ++i)
  178.                     if (s_bits[i].id == LOWORD(wParam)) {
  179.                         if (IsDlgButtonChecked(hdlg, s_bits[i].id))
  180.                             g_dTVDriver.memoryWriteBYTE(s_bits[i].offset, g_dTVDriver.memoryReadBYTE(s_bits[i].offset) | s_bits[i].bit);
  181.                         else
  182.                             g_dTVDriver.memoryWriteBYTE(s_bits[i].offset, g_dTVDriver.memoryReadBYTE(s_bits[i].offset) & ~s_bits[i].bit);
  183.                         break;
  184.                     }
  185.             break;
  186.         }
  187.         return TRUE;
  188.  
  189.     case WM_HSCROLL:
  190.         if (lParam) {
  191.             int pos = SendMessage((HWND)lParam, TBM_GETPOS, 0, 0);
  192.  
  193.             switch(GetWindowLong((HWND)lParam, GWL_ID)) {
  194.             case IDC_SLIDER_LUMAPEAKEVEN:
  195.                 g_dTVDriver.memoryWriteBYTE(0x40, (g_dTVDriver.memoryReadBYTE(0x40)&~0x18) + ((pos&3)<<3));
  196.                 return TRUE;
  197.             case IDC_SLIDER_LUMAPEAKODD:
  198.                 g_dTVDriver.memoryWriteBYTE(0xC0, (g_dTVDriver.memoryReadBYTE(0xC0)&~0x18) + ((pos&3)<<3));
  199.                 return TRUE;
  200.             case IDC_SLIDER_CORING:
  201.                 g_dTVDriver.memoryWriteBYTE(0x48, (g_dTVDriver.memoryReadBYTE(0x48)&~0x60) + ((pos&3)<<5));
  202.                 return TRUE;
  203.             case IDC_SLIDER_LEFT:
  204.             case IDC_SLIDER_RIGHT:
  205.                 {
  206.                     int left = SendDlgItemMessage(hdlg, IDC_SLIDER_LEFT, TBM_GETPOS, 0, 0);
  207.                     int right = SendDlgItemMessage(hdlg, IDC_SLIDER_RIGHT, TBM_GETPOS, 0, 0);
  208.  
  209.                     if (right < left)
  210.                         right = left;
  211.  
  212.                     int hactive = ((g_dTVDriver.memoryReadBYTE(0x00C)&0x003)<<8)+g_dTVDriver.memoryReadBYTE(0x01c);
  213.                     int hscale = MulDiv(right-left, 512, hactive);
  214.  
  215.                     if (hscale < 4096)
  216.                         hscale = 4096;
  217.  
  218.                     int hdelay = MulDiv(left, 512, hscale);
  219.  
  220.                     g_dTVDriver.memoryWriteBYTE(0x20, (hscale-4096)>>8);
  221.                     g_dTVDriver.memoryWriteBYTE(0xA0, (hscale-4096)>>8);
  222.                     g_dTVDriver.memoryWriteBYTE(0x24, hscale&0xff);
  223.                     g_dTVDriver.memoryWriteBYTE(0xA4, hscale&0xff);
  224.                     g_dTVDriver.memoryWriteBYTE(0x18, hdelay&0xfe);
  225.                     g_dTVDriver.memoryWriteBYTE(0x98, hdelay&0xfe);
  226.                     g_dTVDriver.memoryWriteBYTE(0x0C, (g_dTVDriver.memoryReadBYTE(0x0C) & 0xf3) + ((hdelay&0x300)>>6));
  227.                     g_dTVDriver.memoryWriteBYTE(0x8C, (g_dTVDriver.memoryReadBYTE(0x8C) & 0xf3) + ((hdelay&0x300)>>6));
  228.                 }
  229.                 return TRUE;
  230.             case IDC_SLIDER_VDELAY:
  231.                 g_dTVDriver.memoryWriteBYTE(0x10, pos&0xff);
  232.                 g_dTVDriver.memoryWriteBYTE(0x90, pos&0xff);
  233.                 g_dTVDriver.memoryWriteBYTE(0x0C, (g_dTVDriver.memoryReadBYTE(0x0C) & 0x3f) + ((pos&0x300)>>2));
  234.                 g_dTVDriver.memoryWriteBYTE(0x8C, (g_dTVDriver.memoryReadBYTE(0x8C) & 0x3f) + ((pos&0x300)>>2));
  235.                 return TRUE;
  236.             case IDC_SLIDER_AGCDELAY:
  237.                 g_dTVDriver.memoryWriteBYTE(0x60, pos);
  238.                 return TRUE;
  239.             case IDC_SLIDER_BURSTDELAY:
  240.                 g_dTVDriver.memoryWriteBYTE(0x64, pos);
  241.                 return TRUE;
  242.             }
  243.         }
  244.         break;
  245.     }
  246.     return FALSE;
  247. }
  248.  
  249. void CaptureDisplayBT848Tweaker(HWND hwndParent) {
  250.     const char *const g_dtvEntryPts[]={
  251.         "isDriverOpened",
  252.         "pciGetHardwareResources",
  253.         "memoryAlloc",
  254.         "memoryFree",
  255.         "memoryMap",
  256.         "memoryUnmap",
  257.         "memoryReadBYTE",
  258.         "memoryReadWORD",
  259.         "memoryReadDWORD",
  260.         "memoryWriteBYTE",
  261.         "memoryWriteWORD",
  262.         "memoryWriteDWORD",
  263.     };
  264.  
  265.     // Attempt to load dTV driver
  266.  
  267.     HMODULE hmodDTV = LoadLibrary("dTVdrv.dll");
  268.  
  269.     try {
  270.  
  271.         if (!hmodDTV)
  272.             throw MyWin32Error("Cannot load dTV driver: %%s\n\nThis function requires the dTVdrv.dll, dTVdrvNT.sys, and dTVdrv95.vxd "
  273.                 "files from dTV to be copied into the VirtualDub program directory.", GetLastError());
  274.  
  275.         // dTV driver is loaded -- obtain entry points.
  276.  
  277.         FARPROC *ppEntries = (FARPROC *)&g_dTVDriver;
  278.  
  279.         for(int i=0; i<(sizeof g_dtvEntryPts / sizeof g_dtvEntryPts[0]); ++i)
  280.             if (!(ppEntries[i] = GetProcAddress(hmodDTV, g_dtvEntryPts[i])))
  281.                 throw MyError("Cannot load dTV driver: entry point \"%s\" is missing!", g_dtvEntryPts[i]);
  282.  
  283.         // Map the registers.
  284.  
  285.         InitializeBT8X8();
  286.  
  287.         // Display the dialog.
  288.  
  289.         DialogBox(g_hInst, MAKEINTRESOURCE(IDD_CAPTURE_BT8X8), hwndParent, CaptureBT848TweakerDlgProc);
  290.  
  291.         // Unmap the registers.
  292.  
  293.         DeinitializeBT8X8();
  294.  
  295.     } catch(MyError e) {
  296.         e.post(hwndParent, g_szError);
  297.     }
  298.  
  299.     if (hmodDTV)
  300.         FreeLibrary(hmodDTV);
  301. }
  302.